package com.niiwoo.civet.trade.service.local.loan.credit;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.dangdang.ddframe.rdb.sharding.hint.HintManagerHolder;
import com.niiwoo.civet.trade.constant.LoanFlowMqConstant;
import com.niiwoo.civet.trade.constant.MqConstant;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.*;
import com.niiwoo.civet.trade.dto.common.TcCreditAmountResultDTO;
import com.niiwoo.civet.trade.dto.request.ProjectFlowRequestDTO;
import com.niiwoo.civet.trade.dto.request.loan.ProjectFlowExecuteRuntimeDTO;
import com.niiwoo.civet.trade.dto.request.loan.ProjectWaitPublishReqDTO;
import com.niiwoo.civet.trade.enums.*;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.trade.service.dubbo.loan.core.ISpeedLoanFactory;
import com.niiwoo.civet.trade.service.local.flowexecute.ProjectFlowExecuteService;
import com.niiwoo.civet.trade.service.local.loan.TianchengModelParseService;
import com.niiwoo.civet.trade.service.local.loan.antifraud.LoanAntiFraudLocalService;
import com.niiwoo.civet.trade.service.local.notify.Notifiers;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.civet.user.dto.request.AddUserLoanLimitRequestDTO;
import com.niiwoo.civet.user.dto.response.credit.BasicInfoDTO;
import com.niiwoo.civet.user.dto.response.credit.ContactPersonInfoDTO;
import com.niiwoo.civet.user.dto.response.credit.CreditCardTeCreditScoreCardDTO;
import com.niiwoo.civet.user.dto.response.credit.CreditScoreCardDTO;
import com.niiwoo.civet.user.dto.response.credit.SocialSecurityTeCreditScoreCardDTO;
import com.niiwoo.civet.user.dto.response.credit.TianchengCreditBaseInfoResponseDTO;
import com.niiwoo.civet.user.dto.response.credit.WorkInfoDTO;
import com.niiwoo.civet.user.enums.FromSourceEnum;
import com.niiwoo.civet.user.enums.LibraLoanLimitEnum;
import com.niiwoo.civet.user.enums.ProductTypeEnum;
import com.niiwoo.civet.user.enums.TianchengCallbackEventEnum;
import com.niiwoo.civet.user.service.LibraLoanLimitDubboService;
import com.niiwoo.civet.user.service.TianchengDataDubboService;
import com.niiwoo.civet.user.service.UserForbidDubboService;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import com.niiwoo.tripod.tiancheng.component.TianchengAgainstFakeV2Service;
import com.niiwoo.tripod.tiancheng.enums.AgainstFakeErrorCodeEnum;
import com.niiwoo.tripod.tiancheng.enums.AntifraudFromSourceEnum;
import com.niiwoo.tripod.tiancheng.enums.FunctionCodeEnum;
import com.niiwoo.tripod.tiancheng.request.afp.*;
import com.niiwoo.tripod.tiancheng.request.afp.dto.TCBasicInfo;
import com.niiwoo.tripod.tiancheng.response.common.AgainstFakeV2Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 授信额度处理
 * Created by dell on 2018/4/19.
 * Description：civet-app
 */
@Slf4j
@Service
public class CreditAmountLocalService {

    @Value("${web-http-url}")
    private String webHttpUrl;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private ProjectFlowExecuteService projectFlowExecuteService;
    @Autowired
    private LoanAntiFraudLocalService loanAntiFraudLocalService;
    @Autowired
    private TianchengAgainstFakeV2Service againstFakeV2Service;
    @Autowired
    private ProjectFlowExecuteRuntimeMapperExt projectFlowExecuteRuntimeMapperExt;
    @Autowired
    private ProjectMapperExt projectMapperExt;
    @Autowired
    private TianChengRequestRecordMapperExt tianChengRequestRecordMapperExt;
    @Autowired
    private LoanBusinessInfoMapperExt loanBusinessInfoMapperExt;
    @Autowired
    private ProjectCreditAmountMapperExt projectCreditAmountMapperExt;
    @Autowired
    private ISpeedLoanFactory iSpeedLoanFactory;
    @Autowired
    private CreditAmountLocalService creditAmountLocalService;
    @Autowired
    private CreditAmountNotificationsService creditAmountNotificationsService;
    @Autowired
    private Notifiers notifiers;

    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;
    @Reference(version = "1.0.0")
    private UserForbidDubboService userForbidDubboService;
    @Reference(version = "1.0.0")
    private TradeConfigDubboService tradeConfigDubboService;
    @Reference(version = "1.0.0")
    private TianchengDataDubboService tianchengDataDubboService;
    @Reference(version = "1.0.0")
    private LibraLoanLimitDubboService libraLoanLimitDubboService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 查询运行中流程
     *
     * @param flowExecuteId
     * @return
     */
    public ProjectFlowExecuteRuntime queryProjectFlowExecuteRuntime(Long flowExecuteId) {
        //强制走主库
        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
        return projectFlowExecuteRuntimeMapperExt.selectByPrimaryKey(flowExecuteId);
    }

    /**
     * 查询标的
     *
     * @param projectId
     * @return
     */
    public Project queryProjectById(Long projectId) {
        return projectMapperExt.selectByPrimaryKey(projectId);
    }


    /**
     * 发起卡贷天秤授信请求（小易借）
     *
     * @param flowExecuteRuntime
     * @return
     */
    public AgainstFakeV2Response callTcSmallLoanCredit(ProjectFlowExecuteRuntime flowExecuteRuntime) {
        String orderId = String.valueOf(snowflakeIdWorker.nextId());
        Long projectId = flowExecuteRuntime.getProjectId();
        String borrowUserId = flowExecuteRuntime.getBorrowUserId();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);
        Boolean isFirstLoan = loanAntiFraudLocalService.firstLoan(borrowUserId);
        //获取天秤用户基本信息
        BasicInfoDTO baseInfoDTO = tianchengDataDubboService.getBasicInfo(borrowUserId);
        TCBasicInfo tcBasicInfo = TianchengModelParseService.parseBaseInfo(baseInfoDTO);

        //封装天秤请求参数
        MicroCreditRequest microCreditRequest = new MicroCreditRequest();
        microCreditRequest.setReserve(String.valueOf(flowExecuteRuntime.getFlowExecuteId()));   // 预留字段
        microCreditRequest.setTransNo(orderId);
        microCreditRequest.setTransDate(new Date());
        microCreditRequest.setOrder_id(orderId);
        microCreditRequest.setProject_id(projectId.toString());
        microCreditRequest.setBasic_info(tcBasicInfo);
        microCreditRequest.setFrom_source(FromSourceEnum.TongDunFromSource.SPEED_LOAN_SMALL.getValue());
        microCreditRequest.setApply_amount(project.getContractAmount().doubleValue());
        microCreditRequest.setIs_multi_borrow(isFirstLoan ? 1 : 0);
        microCreditRequest.setNotify_url(
                TianchengModelParseService.buildNotifyUrl(
                        webHttpUrl, TianchengCallbackEventEnum.SPEED_LOAN_CREDIT,
                        projectId.toString(), ProjectTypeEnum.SMALL_LOAN,
                        FunctionCodeEnum.LIBRA_MICROFINANCE_LOAN));
        log.info("【（小易借）发起天秤授信额度请求 参数】microCreditRequest：{}", JSON.toJSONString(microCreditRequest));

        CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.microCredit(microCreditRequest);
        AgainstFakeV2Response againstFakeV2Response = null;
        try {
            againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
        } catch (Exception e) {
            log.error("【（小易借）发起天秤授信额度请求 结果 》》》 异常】microCreditRequest:{}", JSON.toJSONString(microCreditRequest), e);
            throw new BizException("TRD40006");
        }
        //新增天秤请求记录
        insertTcRequestRecord(flowExecuteRuntime, orderId, FunctionCodeEnum.LIBRA_MICROFINANCE_LOAN);
        return againstFakeV2Response;
    }


    /**
     * 社保贷
     *
     * @param flowExecuteRuntime
     * @return
     */
    public AgainstFakeV2Response callTcSocialSecurityCredit(ProjectFlowExecuteRuntime flowExecuteRuntime) {
        String orderId = String.valueOf(snowflakeIdWorker.nextId());
        Long projectId = flowExecuteRuntime.getProjectId();
        String borrowUserId = flowExecuteRuntime.getBorrowUserId();
        Boolean isFirstLoan = loanAntiFraudLocalService.firstLoan(borrowUserId);
        //获取天秤用户基本信息
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(borrowUserId);
        BasicInfoDTO baseInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();//tianchengDataDubboService.getBasicInfo(borrowUserId);
        List<ContactPersonInfoDTO> contacts = tianchengCreditBaseInfoResponseDTO.getContacts();
        //TCBasicInfo tcBasicInfo = TianchengModelParseService.parseBaseInfo(baseInfoDTO);
        //查询用户天秤额度评分卡所需参数
        CreditScoreCardDTO creditScoreCardDTO = tianchengDataDubboService.queryCreditScoreCardParam(borrowUserId, FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_LOAN.getHeadFunctionCode());

        //封装天秤请求参数
        SocialCreditRequest socialCreditRequest = new SocialCreditRequest();
        socialCreditRequest.setReserve(String.valueOf(flowExecuteRuntime.getFlowExecuteId()));   // 预留字段
        socialCreditRequest.setTransNo(orderId);
        socialCreditRequest.setTransDate(new Date());
        socialCreditRequest.setOrder_id(orderId);
        socialCreditRequest.setProject_id(projectId.toString());
        socialCreditRequest.setBasic_info(TianchengModelParseService.parseBaseInfo(baseInfoDTO));
        socialCreditRequest.setJd_login_name(creditScoreCardDTO.getJd_login_name());
        socialCreditRequest.setJd_auth(creditScoreCardDTO.getJd_auth());
        socialCreditRequest.setXx_auth(creditScoreCardDTO.getXx_auth());
        socialCreditRequest.setIs_multi_borrow(isFirstLoan ? 1 : 0);
        socialCreditRequest.setYx_auth(creditScoreCardDTO.getYx_auth());
        socialCreditRequest.setYx_entry_id(creditScoreCardDTO.getYx_entry_id());
        socialCreditRequest.setYx_login_name(creditScoreCardDTO.getYx_login_name());
        socialCreditRequest.setContact_person(TianchengModelParseService.parseContactPersonInfo(contacts));
        socialCreditRequest.setNotify_url(
                TianchengModelParseService.buildNotifyUrl(
                        webHttpUrl, TianchengCallbackEventEnum.SPEED_LOAN_CREDIT,
                        projectId.toString(), ProjectTypeEnum.SOCIAL_SECURITY_LOAN,
                        FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_LOAN));
        log.info("【（社保贷）发起天秤授信额度请求 参数】socialCreditRequest：{}", JSON.toJSONString(socialCreditRequest));

        CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.socialCredit(socialCreditRequest);
        AgainstFakeV2Response againstFakeV2Response = null;
        try {
            againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
        } catch (Exception e) {
            log.error("【（社保贷）发起天秤授信额度请求 结果 》》》 异常】socialCreditRequest:{}", JSON.toJSONString(socialCreditRequest), e);
            throw new BizException("TRD40006");
        }
        //新增天秤请求记录
        insertTcRequestRecord(flowExecuteRuntime, orderId, FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_LOAN);
        return againstFakeV2Response;
    }

    private Date getProjectSubmitTime(String userId, Long projectId) {
        Project project = projectMapperExt.selectProjectByUserIdProjectId(userId, projectId);
        return project.getSubmitTime();
    }

    private int getTeAuth(Date projectSubmitTime, Date teAuthTime) {
        if (teAuthTime == null) {
            return 0;
        }
        return projectSubmitTime.before(teAuthTime) ? 1 : 0;
    }

    /**
     * 社保贷
     *
     * @param flowExecuteRuntime
     * @return
     */
    public AgainstFakeV2Response callTcSocialSecurityCreditForTe(ProjectFlowExecuteRuntime flowExecuteRuntime) {
        String orderId = String.valueOf(snowflakeIdWorker.nextId());
        Long projectId = flowExecuteRuntime.getProjectId();
        String borrowUserId = flowExecuteRuntime.getBorrowUserId();
        Date projectSubmitTime = getProjectSubmitTime(borrowUserId, projectId);
        //获取天秤用户基本信息
        BasicInfoDTO baseInfoDTO = tianchengDataDubboService.getBasicInfo(borrowUserId);
        TCBasicInfo tcBasicInfo = TianchengModelParseService.parseBaseInfo(baseInfoDTO);
        //查询用户天秤额度评分卡所需参数
        SocialSecurityTeCreditScoreCardDTO socialSecurityTeCreditScoreCardDTO = tianchengDataDubboService.queryCreditScoreCardParamForSocialSecurityTe(borrowUserId);

        //封装天秤请求参数
        SocialCreditIncreaseAmountRequest socialCreditRequest = new SocialCreditIncreaseAmountRequest();
        socialCreditRequest.setReserve(String.valueOf(flowExecuteRuntime.getFlowExecuteId()));   // 预留字段
        socialCreditRequest.setTransNo(orderId);
        socialCreditRequest.setTransDate(new Date());
        socialCreditRequest.setOrder_id(orderId);
        socialCreditRequest.setProject_id(projectId.toString());
        socialCreditRequest.setBasic_info(tcBasicInfo);
        socialCreditRequest.setJd_login_name(socialSecurityTeCreditScoreCardDTO.getJd_login_name());
        socialCreditRequest.setJd_te_auth(getTeAuth(projectSubmitTime, socialSecurityTeCreditScoreCardDTO.getJdAuthTime()));
        socialCreditRequest.setXx_te_auth(getTeAuth(projectSubmitTime, socialSecurityTeCreditScoreCardDTO.getXxAuthTime()));
        socialCreditRequest.setYx_te_auth(getTeAuth(projectSubmitTime, socialSecurityTeCreditScoreCardDTO.getYxAuthTime()));
        socialCreditRequest.setYx_entry_id(socialSecurityTeCreditScoreCardDTO.getYx_entry_id());
        socialCreditRequest.setYx_login_name(socialSecurityTeCreditScoreCardDTO.getYx_login_name());
        socialCreditRequest.setCurrent_credit(this.getCreditAmount(projectId));
        socialCreditRequest.setNotify_url(
                TianchengModelParseService.buildNotifyUrl(
                        webHttpUrl, TianchengCallbackEventEnum.SPEED_LOAN_CREDIT,
                        projectId.toString(), ProjectTypeEnum.SOCIAL_SECURITY_LOAN,
                        FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_TE_LOAN));
        log.info("【（社保贷）发起天秤提额授信额度请求 参数】socialCreditRequest：{}", JSON.toJSONString(socialCreditRequest));

        CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.socialCreditIncreaseTheAmount(socialCreditRequest);
        AgainstFakeV2Response againstFakeV2Response = null;
        try {
            againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
        } catch (Exception e) {
            log.error("【（社保贷）发起天秤提额授信额度请求 结果 》》》 异常】socialCreditRequest:{}", JSON.toJSONString(socialCreditRequest), e);
            throw new BizException("TRD40006");
        }
        //新增天秤请求记录
        insertTcRequestRecord(flowExecuteRuntime, orderId, FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_TE_LOAN);
        return againstFakeV2Response;
    }

    private double getCreditAmount(Long projectId) {
        ProjectCreditAmount projectCreditAmount = projectCreditAmountMapperExt.selectByPrimaryKey(projectId);
        if (projectCreditAmount == null) {
            return 0;
        }
        BigDecimal creditAmount = projectCreditAmount.getCreditAmount();
        return creditAmount == null ? 0 : creditAmount.doubleValue();
    }

    /**
     * 信用卡贷
     *
     * @param flowExecuteRuntime
     * @return
     */
    public AgainstFakeV2Response callTcCreditCardLoanCredit(ProjectFlowExecuteRuntime flowExecuteRuntime) {
        String orderId = String.valueOf(snowflakeIdWorker.nextId());
        Long projectId = flowExecuteRuntime.getProjectId();
        String borrowUserId = flowExecuteRuntime.getBorrowUserId();
        Boolean isFirstLoan = loanAntiFraudLocalService.firstLoan(borrowUserId);
        //获取天秤用户基本信息
        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(borrowUserId);
        BasicInfoDTO baseInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();//tianchengDataDubboService.getBasicInfo(borrowUserId);
        List<ContactPersonInfoDTO> contacts = tianchengCreditBaseInfoResponseDTO.getContacts();
        //TCBasicInfo tcBasicInfo = TianchengModelParseService.parseBaseInfo(baseInfoDTO);
        //查询用户天秤额度评分卡所需参数
        CreditScoreCardDTO creditScoreCardDTO = tianchengDataDubboService.queryCreditScoreCardParam(borrowUserId, FunctionCodeEnum.LIBRA_CREDIT_CARD_LOAN_TWO.getHeadFunctionCode());

        CreditCardRequest creditCardRequest = new CreditCardRequest();
        creditCardRequest.setReserve(String.valueOf(flowExecuteRuntime.getFlowExecuteId()));   // 预留字段
        creditCardRequest.setTransNo(orderId);
        creditCardRequest.setTransDate(new Date());
        creditCardRequest.setOrder_id(orderId);
        creditCardRequest.setProject_id(projectId.toString());
        creditCardRequest.setBasic_info(TianchengModelParseService.parseBaseInfo(baseInfoDTO));
        creditCardRequest.setYx_entry_id(creditScoreCardDTO.getYx_entry_id());
        creditCardRequest.setYx_login_name(creditScoreCardDTO.getYx_login_name());
        creditCardRequest.setJd_login_name(creditScoreCardDTO.getJd_login_name());
        creditCardRequest.setJd_auth(creditScoreCardDTO.getJd_auth());
        creditCardRequest.setXx_auth(creditScoreCardDTO.getXx_auth());
        creditCardRequest.setIs_multi_borrow(isFirstLoan ? 1 : 0);
        creditCardRequest.setInsurance_auth(creditScoreCardDTO.getInsurance_auth());
        creditCardRequest.setContact_person(TianchengModelParseService.parseContactPersonInfo(contacts));
        creditCardRequest.setNotify_url(
                TianchengModelParseService.buildNotifyUrl(
                        webHttpUrl, TianchengCallbackEventEnum.SPEED_LOAN_CREDIT,
                        projectId.toString(), ProjectTypeEnum.CREDIT_CARD_LOAN,
                        FunctionCodeEnum.LIBRA_CREDIT_CARD_LOAN_TWO));
        log.info("【（信用卡贷）发起天秤授信额度请求 参数】creditCardRequest：{}", JSON.toJSONString(creditCardRequest));

        CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.creditCardTwo(creditCardRequest);
        AgainstFakeV2Response againstFakeV2Response = null;
        try {
            againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
        } catch (Exception e) {
            log.error("【（信用卡贷）发起天秤授信额度请求 结果 》》》 异常】creditCardRequest:{}", JSON.toJSONString(creditCardRequest), e);
            throw new BizException("TRD40006");
        }
        //新增天秤请求记录
        insertTcRequestRecord(flowExecuteRuntime, orderId, FunctionCodeEnum.LIBRA_CREDIT_CARD_LOAN_TWO);
        return againstFakeV2Response;
    }
    
    /**
     * 标准化消费贷额度评分卡
     * 
     * @param flowExecuteRuntime
     * @return
     */
    public AgainstFakeV2Response callTcConsumeLoanCredit(ProjectFlowExecuteRuntime flowExecuteRuntime) {
		String orderId = String.valueOf(snowflakeIdWorker.nextId());
		Long projectId = flowExecuteRuntime.getProjectId();
		String borrowUserId = flowExecuteRuntime.getBorrowUserId();
        
		Project project = projectMapperExt.selectByPrimaryKey(projectId);
		if (null == project) {
			log.error("标准化消费贷授信请求异常:标的不存，ProjectId:{}", projectId);
			throw new BizException("TRD40006");
		}
        
		AgainstFakeV2Response againstFakeV2Response = null;
		try {
	        //获取天秤用户基本信息
	        ConsumeLoanCreditRequest consumeLoanCreditRequest = new ConsumeLoanCreditRequest();
	        
	        // RCE公有参数
	        consumeLoanCreditRequest.setReserve(String.valueOf(flowExecuteRuntime.getFlowExecuteId()));
	        consumeLoanCreditRequest.setTransNo(orderId);
	        consumeLoanCreditRequest.setTransDate(new Date());
	        
	        // 授信相关参数
	        consumeLoanCreditRequest.setOrder_id(orderId);
	        consumeLoanCreditRequest.setProject_id(String.valueOf(projectId));
	        consumeLoanCreditRequest.setApply_amount(project.getContractAmount().doubleValue());
	        consumeLoanCreditRequest.setFrom_source(AntifraudFromSourceEnum.CONSUME_LOAN.getFromSource());
	        consumeLoanCreditRequest.setGps_province(project.getLoanProvince());
	        consumeLoanCreditRequest.setGps_city(project.getLoanCity());
	        consumeLoanCreditRequest.setGps_district(project.getLoanArea());
			consumeLoanCreditRequest.setNotify_url(
					TianchengModelParseService.buildNotifyUrl(webHttpUrl, TianchengCallbackEventEnum.SPEED_LOAN_CREDIT, projectId.toString(), ProjectTypeEnum.CONSUME_LOAN, FunctionCodeEnum.LIBRA_CONSUME_LOAN));
	        consumeLoanCreditRequest.setIs_multi_borrow(loanAntiFraudLocalService.firstLoan(borrowUserId) ? 1 : 0);
	        
	        // 用户信息（基础信息、工作信息、联系人信息）
	        TianchengCreditBaseInfoResponseDTO tianchengCreditBaseInfoResponseDTO = tianchengDataDubboService.getUserTianchengCreditBaseInfo(flowExecuteRuntime.getBorrowUserId());
	        if (null != tianchengCreditBaseInfoResponseDTO) {
	            BasicInfoDTO basicInfoDTO = tianchengCreditBaseInfoResponseDTO.getBaseInfo();
	            WorkInfoDTO workInfoDTO = tianchengCreditBaseInfoResponseDTO.getWorkInfo();
	            List<ContactPersonInfoDTO> contactPersonInfoDTOList = tianchengCreditBaseInfoResponseDTO.getContacts();
	            if (null != basicInfoDTO) {
	            	consumeLoanCreditRequest.setBasic_info(TianchengModelParseService.parseBaseInfo(basicInfoDTO));
	            }
	            if (null != workInfoDTO) {
	            	consumeLoanCreditRequest.setWork_info(TianchengModelParseService.parseWorkInfo(workInfoDTO));
	            }
	            if (!CollectionUtils.isEmpty(contactPersonInfoDTOList)) {
	            	consumeLoanCreditRequest.setContact_person(TianchengModelParseService.parseContactPersonInfo(contactPersonInfoDTOList));
	            }
	        }
			
			log.info("标准化消费贷授信，请求参数：{}", JSON.toJSONString(consumeLoanCreditRequest));
			CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.consumeLoanCredit(consumeLoanCreditRequest);
			againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
			log.info("标准化消费贷授信，返回结果：{}", JSON.toJSONString(againstFakeV2Response));
		} catch (Exception e) {
			log.error("标准化消费贷授信请求异常，ProjectId：{}, FlowExecuteId:{}", flowExecuteRuntime.getProjectId(), flowExecuteRuntime.getFlowExecuteId(), e);
			throw new BizException("TRD40006");
		}
        
		// 生成天称请求记录
        insertTcRequestRecord(flowExecuteRuntime, orderId, FunctionCodeEnum.LIBRA_CONSUME_LOAN);
        
        return againstFakeV2Response;
    }

    /**
     * 信用卡贷
     *
     * @param flowExecuteRuntime
     * @return
     */
    public AgainstFakeV2Response callTcCreditCardLoanCreditForTe(ProjectFlowExecuteRuntime flowExecuteRuntime) {
        String orderId = String.valueOf(snowflakeIdWorker.nextId());
        Long projectId = flowExecuteRuntime.getProjectId();
        String borrowUserId = flowExecuteRuntime.getBorrowUserId();
        Boolean isFirstLoan = loanAntiFraudLocalService.firstLoan(borrowUserId);
        Date projectSubmitTime = getProjectSubmitTime(borrowUserId, projectId);
        //获取天秤用户基本信息
        BasicInfoDTO baseInfoDTO = tianchengDataDubboService.getBasicInfo(borrowUserId);
        TCBasicInfo tcBasicInfo = TianchengModelParseService.parseBaseInfo(baseInfoDTO);
        //查询用户天秤额度评分卡所需参数
        CreditCardTeCreditScoreCardDTO creditCardTeCreditScoreCardDTO = tianchengDataDubboService.queryCreditScoreCardParamForCreditCardTe(borrowUserId);

        CreditCardIncreaseAmountRequest creditCardRequest = new CreditCardIncreaseAmountRequest();
        creditCardRequest.setReserve(String.valueOf(flowExecuteRuntime.getFlowExecuteId()));   // 预留字段
        creditCardRequest.setTransNo(orderId);
        creditCardRequest.setTransDate(new Date());
        creditCardRequest.setOrder_id(orderId);
        creditCardRequest.setProject_id(projectId.toString());
        creditCardRequest.setBasic_info(tcBasicInfo);
        creditCardRequest.setJd_login_name(creditCardTeCreditScoreCardDTO.getJd_login_name());
        creditCardRequest.setJd_te_auth(getTeAuth(projectSubmitTime, creditCardTeCreditScoreCardDTO.getJdAuthTime()));
        creditCardRequest.setXx_te_auth(getTeAuth(projectSubmitTime, creditCardTeCreditScoreCardDTO.getXxAuthTime()));
        creditCardRequest.setInsurance_te_auth(getTeAuth(projectSubmitTime, creditCardTeCreditScoreCardDTO.getInsuranceAuthTime()));
        creditCardRequest.setCurrent_credit(this.getCreditAmount(projectId));
        creditCardRequest.setNotify_url(
                TianchengModelParseService.buildNotifyUrl(
                        webHttpUrl, TianchengCallbackEventEnum.SPEED_LOAN_CREDIT,
                        projectId.toString(), ProjectTypeEnum.CREDIT_CARD_LOAN,
                        FunctionCodeEnum.LIBRA_CREDIT_CARD_TE_LOAN));
        log.info("【（信用卡贷）发起天秤提额授信额度请求 参数】creditCardRequest：{}", JSON.toJSONString(creditCardRequest));

        CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.creditCardIncreaseTheAmount(creditCardRequest);
        AgainstFakeV2Response againstFakeV2Response = null;
        try {
            againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
        } catch (Exception e) {
            log.error("【（信用卡贷）发起天秤提额授信额度请求 结果 》》》 异常】creditCardRequest:{}", JSON.toJSONString(creditCardRequest), e);
            throw new BizException("TRD40006");
        }
        //新增天秤请求记录
        insertTcRequestRecord(flowExecuteRuntime, orderId, FunctionCodeEnum.LIBRA_CREDIT_CARD_TE_LOAN);
        return againstFakeV2Response;
    }    

    /**
     * 创建天秤请求记录
     *
     * @param flowExecuteRuntime
     * @param orderId
     * @param functionCodeEnum
     */
    public void insertTcRequestRecord(ProjectFlowExecuteRuntime flowExecuteRuntime, String orderId, FunctionCodeEnum functionCodeEnum) {
        TianChengRequestRecord tianChengRequestRecord = new TianChengRequestRecord();
        tianChengRequestRecord.setId(snowflakeIdWorker.nextId());
        tianChengRequestRecord.setBorrowUserId(flowExecuteRuntime.getBorrowUserId());
        tianChengRequestRecord.setFlowExecuteId(flowExecuteRuntime.getFlowExecuteId());
        tianChengRequestRecord.setProjectId(flowExecuteRuntime.getProjectId());
        tianChengRequestRecord.setOrderId(orderId);
        tianChengRequestRecord.setFunctionCode(functionCodeEnum.getHeadFunctionCode());
        tianChengRequestRecord.setCreateTime(new Date());
        tianChengRequestRecordMapperExt.insertSelective(tianChengRequestRecord);
    }

    /**
     * 查询天秤入库记录
     *
     * @param flowExecuteId
     * @param functionCode
     * @return
     */
    public TianChengRequestRecord queryTcRequestRecord(Long flowExecuteId, String functionCode) {
        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
        return tianChengRequestRecordMapperExt.queryTcRequestRecord(flowExecuteId, functionCode);
    }

    /**
     * 批量查询天秤入库记录
     *
     * @param flowExecuteIds
     * @param functionCode
     * @return
     */
    public List<TianChengRequestRecord> queryBatchTcRequestRecord(List<Long> flowExecuteIds, String functionCode) {
        return tianChengRequestRecordMapperExt.queryBatchTcRequestRecord(flowExecuteIds, functionCode);
    }

    /**
     * 天秤授信额度评分卡回调
     *
     * @param functionCode
     * @param amountResultDTO
     */
    public void scoreCardTcCallback(String functionCode, TcCreditAmountResultDTO amountResultDTO) {
        log.info("【天秤授信额度评分卡回调】functionCode={} flowExecuteId={} amountResultDTO={}", functionCode, amountResultDTO.getReserve(), amountResultDTO);
        Long flowExecuteId = Long.valueOf(amountResultDTO.getReserve());

        //查询当前流程信息
        ProjectFlowExecuteRuntime projectFlowExecuteRuntime = this.queryProjectFlowExecuteRuntime(flowExecuteId);
        String userId = projectFlowExecuteRuntime.getBorrowUserId();
        Long projectId = projectFlowExecuteRuntime.getProjectId();
        Byte projectType = projectFlowExecuteRuntime.getProjectType();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);

        LoanBusinessInfo loanBusinessInfo = null;
		// 小易贷授信
		if (FunctionCodeEnum.LIBRA_MICROFINANCE_LOAN.getHeadFunctionCode().equalsIgnoreCase(functionCode)) {
			loanBusinessInfo = loanBusinessInfoMapperExt.selectByProductType(ProjectTypeEnum.SMALL_LOAN.getValue());
		}
		// 社保贷授信		
		else if (FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_LOAN.getHeadFunctionCode().equalsIgnoreCase(functionCode)) {
			loanBusinessInfo = loanBusinessInfoMapperExt.selectByProductType(ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue());
		}
		// 信用卡贷授信
		else if (FunctionCodeEnum.LIBRA_CREDIT_CARD_LOAN_TWO.getHeadFunctionCode().equalsIgnoreCase(functionCode)) {
			loanBusinessInfo = loanBusinessInfoMapperExt.selectByProductType(ProjectTypeEnum.CREDIT_CARD_LOAN.getValue());
		}
		// 消费贷授信
		else if (FunctionCodeEnum.LIBRA_CONSUME_LOAN.getHeadFunctionCode().equalsIgnoreCase(functionCode)) {
			loanBusinessInfo = loanBusinessInfoMapperExt.selectByProductType(ProjectTypeEnum.CONSUME_LOAN.getValue());
		}

        //入库标的授信额度
        Date currDate = new Date();
        // shardingjdbc 强制走主库
        if (!HintManagerHolder.isMasterRouteOnly()) {
            HintManagerHolder.clear();
            HintManager hintManager = HintManager.getInstance();
            hintManager.setMasterRouteOnly();
        }
        ProjectCreditAmount record = projectCreditAmountMapperExt.selectByPrimaryKey(projectId);
        if (record == null) {
            record = new ProjectCreditAmount();
            record.setProjectId(projectId);
            record.setUserId(userId);
            record.setProjectType(projectType);
            record.setFirstApplyAmount(project.getContractAmount());
            record.setLastApplyAmount(project.getContractAmount());
            record.setMixLoanAmount(loanBusinessInfo.getMinAmount());
            record.setCreditAmount(amountResultDTO.getCreditAmount());
            record.setCreateTime(currDate);
            record.setUpdateTime(currDate);
            projectCreditAmountMapperExt.insertSelective(record);
        }else {
            record.setProjectId(projectId);
            record.setUserId(userId);
            record.setProjectType(projectType);
            record.setFirstApplyAmount(project.getContractAmount());
            record.setLastApplyAmount(project.getContractAmount());
            record.setMixLoanAmount(loanBusinessInfo.getMinAmount());
            record.setCreditAmount(amountResultDTO.getCreditAmount());
            record.setUpdateTime(currDate);
            projectCreditAmountMapperExt.updateByPrimaryKeySelective(record);
        }

        //通过，更新标的状态
        updateProjectStatus(project, ProjectStatusEnum.CHECKING, ProjectSubStatusEnum.CHECKING_CREDIT_AMOUNT);
        //流到下一个流程节点（系统审核）
        //projectFlowExecuteService.initNextStepProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_LIMIT_SCORE_BACK, LoanNodeTypeEnum.LOAN_SYSTEM_AUDIT, LoanFlowMqConstant.Queue.LOAN_SYSTEM_AUDIT_QUEUE);
    }


    /**
     * 补漏查询（针对于天秤异步回调超时的场景）
     *
     * @param flowExecuteRuntimeDTO
     */
    public void amountScoreBareQuery(ProjectFlowExecuteRuntimeDTO flowExecuteRuntimeDTO) {
        Long flowExecuteId = flowExecuteRuntimeDTO.getFlowExecuteId();
        Byte projectType = flowExecuteRuntimeDTO.getProjectType();
        Long projectId = flowExecuteRuntimeDTO.getProjectId();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);

        FunctionCodeEnum functionCodeEnum = null;
        if (ProjectTypeEnum.SMALL_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_MICROFINANCE_LOAN;
        } else if (ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_LOAN;
        } else if (ProjectTypeEnum.CREDIT_CARD_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_CREDIT_CARD_LOAN_TWO;
        } else if (ProjectTypeEnum.CONSUME_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_CONSUME_LOAN;
        }
        
        TianChengRequestRecord tianChengRequestRecord = queryTcRequestRecord(flowExecuteId, functionCodeEnum.getHeadFunctionCode());
        if (tianChengRequestRecord != null) {
            KaDaiRepairServiceRequest request = new KaDaiRepairServiceRequest();
            request.setTransNo(String.valueOf(snowflakeIdWorker.nextId()));
            request.setTransDate(new Date());
            request.setOrder_id(tianChengRequestRecord.getOrderId());

            CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.repairService(request);
            try {
                AgainstFakeV2Response againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
                log.info("天秤授信额度评分卡补漏={}.", JSONObject.toJSONString(againstFakeV2Response));
                Integer code = againstFakeV2Response.getCode();

                TcCreditAmountResultDTO amountResultDTO = new TcCreditAmountResultDTO();
                amountResultDTO.setReserve(String.valueOf(flowExecuteId));
                amountResultDTO.setStatus(againstFakeV2Response.getCode());
                amountResultDTO.setMessage("");

                //成功
                if (AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() != code) {
                    log.error("天秤授信额度评分卡回调处理异常：{}", JSONObject.toJSONString(againstFakeV2Response));
                    amountResultDTO.setCreditAmount(new BigDecimal(-1));
                } else {
                    try {
                        JSONObject msgBodyJSON = JSONObject.parseObject(againstFakeV2Response.getBody());
                        amountResultDTO.setCreditAmount(new BigDecimal(msgBodyJSON.getDouble("credit_amount")));
                    } catch (Exception e) {
                        amountResultDTO.setCreditAmount(new BigDecimal(-1));
                    }
                }

                creditAmountLocalService.scoreCardTcCallback(functionCodeEnum.getHeadFunctionCode(), amountResultDTO);
            } catch (Exception e) {
                //结束流程
                log.error("天秤授信额度评分卡回调处理异常,流程ID={}.", flowExecuteId, e);
            } finally {
                //流到下一个流程节点（系统审核）
                projectFlowExecuteService.initNextStepProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_LIMIT_SCORE_BACK, LoanNodeTypeEnum.LOAN_SYSTEM_AUDIT, LoanFlowMqConstant.Queue.LOAN_SYSTEM_AUDIT_QUEUE);
            }
        }
    }

    /**
     * 更新标的状态
     *
     * @param project
     * @param projectStatusEnum
     * @param projectSubStatusEnum
     */
    public void updateProjectStatus(Project project, ProjectStatusEnum projectStatusEnum, ProjectSubStatusEnum projectSubStatusEnum) {
        project.setStatus(projectStatusEnum.getStatus());
        project.setSubStatus(projectSubStatusEnum.getSubStatus());
        project.setUpdateTime(new Date());
        projectMapperExt.updateByUserIdProjectSelective(project);
    }

    /**
     * 提额成功更新标的状态
     *
     * @param project
     * @param projectStatusEnum
     * @param projectSubStatusEnum
     */
    public void updateTeProjectStatus(Project project, ProjectStatusEnum projectStatusEnum, ProjectSubStatusEnum projectSubStatusEnum, TeProjectFlagEnum teProjectFlagEnum) {
        project.setStatus(projectStatusEnum.getStatus());
        project.setSubStatus(projectSubStatusEnum.getSubStatus());
        project.setTeProjectFlag(teProjectFlagEnum.getValue());
        project.setUpdateTime(new Date());
        projectMapperExt.updateByUserIdProjectSelective(project);
    }

    /**
     * 流标
     *
     * @param projectId
     */
    public void flowProject(Long projectId) {
        ProjectFlowRequestDTO projectFlowRequestDTO = new ProjectFlowRequestDTO();
        projectFlowRequestDTO.setProjectId(projectId);
        projectFlowRequestDTO.setSubStatus(ProjectSubStatusEnum.MISCARRY_LOAN_FAKE_FAILED);
        projectDubboService.flow(projectFlowRequestDTO);
    }


    /**
     * 提额天秤授信额度评分卡回调
     *
     * @param functionCode
     * @param amountResultDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void teScoreCardTcCallback(String functionCode, TcCreditAmountResultDTO amountResultDTO) {
        log.info("【提额天秤授信额度评分卡回调】functionCode={} flowExecuteId={} amountResultDTO={}", functionCode, amountResultDTO.getReserve(), amountResultDTO);
        Long flowExecuteId = Long.valueOf(amountResultDTO.getReserve());

        //查询当前流程信息
        ProjectFlowExecuteRuntime projectFlowExecuteRuntime = this.queryProjectFlowExecuteRuntime(flowExecuteId);
        String userId = projectFlowExecuteRuntime.getBorrowUserId();
        Long projectId = projectFlowExecuteRuntime.getProjectId();
        Byte projectType = projectFlowExecuteRuntime.getProjectType();
        Project project = projectMapperExt.selectByPrimaryKey(projectId);

        LoanBusinessInfo loanBusinessInfo = null;
        if (FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_TE_LOAN.getHeadFunctionCode().equalsIgnoreCase(functionCode)) {
            loanBusinessInfo = loanBusinessInfoMapperExt.selectByProductType(ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue());

            //信用卡贷授信
        } else if (FunctionCodeEnum.LIBRA_CREDIT_CARD_TE_LOAN.getHeadFunctionCode().equalsIgnoreCase(functionCode)) {
            loanBusinessInfo = loanBusinessInfoMapperExt.selectByProductType(ProjectTypeEnum.CREDIT_CARD_LOAN.getValue());
        }

        //入库标的授信额度
        Date currDate = new Date();
        ProjectCreditAmount record = projectCreditAmountMapperExt.selectByPrimaryKey(projectId);
        if (record == null) {
            record = new ProjectCreditAmount();
            record.setProjectId(projectId);
            record.setUserId(userId);
            record.setProjectType(projectType);
            record.setFirstApplyAmount(project.getContractAmount());
            record.setLastApplyAmount(project.getContractAmount());
            record.setMixLoanAmount(loanBusinessInfo.getMinAmount());
            record.setCreditAmount(amountResultDTO.getCreditAmount());
            record.setCreateTime(currDate);
            record.setUpdateTime(currDate);
            record.setTeProjectFlag(TeProjectFlagEnum.YES.getValue());
            projectCreditAmountMapperExt.insertSelective(record);
        } else {
            record.setProjectId(projectId);
            record.setUserId(userId);
            record.setProjectType(projectType);
            record.setFirstApplyAmount(project.getContractAmount());
            record.setLastApplyAmount(project.getContractAmount());
            record.setMixLoanAmount(loanBusinessInfo.getMinAmount());
            record.setCreditAmount(amountResultDTO.getCreditAmount());
            record.setUpdateTime(currDate);
            record.setTeProjectFlag(TeProjectFlagEnum.YES.getValue());
            projectCreditAmountMapperExt.updateByPrimaryKeySelective(record);
        }

        // 获取额度后业务处理
        this.teAmountPostProcessing(amountResultDTO, loanBusinessInfo, project);
    }


    public void teAmountScoreBareQuery(ProjectFlowExecuteRuntimeDTO flowExecuteRuntimeDTO) {
        Long flowExecuteId = flowExecuteRuntimeDTO.getFlowExecuteId();
        Byte projectType = flowExecuteRuntimeDTO.getProjectType();
        Integer retryTimes = flowExecuteRuntimeDTO.getRetryTimes();

        //超过三次，直接流标无需重试
        StringBuffer errMsg = new StringBuffer("flowExecuteId=").append(flowExecuteId);
        if (flowExecuteRuntimeDTO.getRetryTimes() >= 3) {
            //结束流程
            errMsg.append("提额评分卡重试超过3次");
            //projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, errMsg.toString());

            teFlowErrorProcess(LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, flowExecuteId, flowExecuteRuntimeDTO.getBorrowUserId(), flowExecuteRuntimeDTO.getProjectId(), errMsg.toString());

            return;
        }

        FunctionCodeEnum functionCodeEnum = null;
        if (ProjectTypeEnum.SOCIAL_SECURITY_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_SOCIAL_SECURITY_LOAN;
        } else if (ProjectTypeEnum.CREDIT_CARD_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_CREDIT_CARD_LOAN_TWO;
        } else if (ProjectTypeEnum.CONSUME_LOAN.getValue().equals(projectType)) {
            functionCodeEnum = FunctionCodeEnum.LIBRA_CONSUME_LOAN;
        }
        TianChengRequestRecord tianChengRequestRecord = queryTcRequestRecord(flowExecuteId, functionCodeEnum.getHeadFunctionCode());
        if (tianChengRequestRecord != null) {
            KaDaiRepairServiceRequest request = new KaDaiRepairServiceRequest();
            request.setTransNo(String.valueOf(snowflakeIdWorker.nextId()));
            request.setTransDate(new Date());
            request.setOrder_id(tianChengRequestRecord.getOrderId());

            CompletableFuture<AgainstFakeV2Response> againstFakeV2ResponseCompletableFuture = againstFakeV2Service.repairService(request);
            try {
                AgainstFakeV2Response againstFakeV2Response = againstFakeV2ResponseCompletableFuture.get();
                log.info("天秤提额授信额度评分卡补漏={}.", JSONObject.toJSONString(againstFakeV2Response));
                Integer code = againstFakeV2Response.getCode();

                TcCreditAmountResultDTO amountResultDTO = new TcCreditAmountResultDTO();
                amountResultDTO.setReserve(String.valueOf(flowExecuteId));
                amountResultDTO.setStatus(againstFakeV2Response.getCode());
                amountResultDTO.setMessage("");

                //成功
                if (AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() == code) {
                    try {
                        JSONObject msgBodyJSON = JSONObject.parseObject(againstFakeV2Response.getBody());
                        amountResultDTO.setCreditAmount(new BigDecimal(msgBodyJSON.getDouble("credit_amount")));
                    } catch (Exception e) {
                        amountResultDTO.setCreditAmount(new BigDecimal(-1));
                    }
                    teScoreCardTcCallback(functionCodeEnum.getHeadFunctionCode(), amountResultDTO);
                    //请求响应（参数错误、数据异常、其它错误）结束流程
                } else if (AgainstFakeErrorCodeEnum.PRAM_ERROR.getErrorCode() == againstFakeV2Response.getCode() ||
                        AgainstFakeErrorCodeEnum.DATA_ABNORMAL.getErrorCode() == againstFakeV2Response.getCode() ||
                        AgainstFakeErrorCodeEnum.OTHER_ERROR.getErrorCode() == againstFakeV2Response.getCode()) {
                    projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, "");

                    teFlowErrorProcess(LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, flowExecuteId, flowExecuteRuntimeDTO.getBorrowUserId(), flowExecuteRuntimeDTO.getProjectId(), errMsg.toString());

                    // 请求响应（获取数据超时、服务忙，稍后重试）更新为异常流程，后续重试
                } else {
                    projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, "", (retryTimes + 1));
                }
            } catch (Exception e) {
                //结束流程
                log.error("天秤授信额度评分卡回调处理异常,流程ID={}.", flowExecuteId, e);
                projectFlowExecuteService.updateProjectFlowExecuteRuntime(flowExecuteId, LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, ProjectFlowExecuteRuntimeNodeStatusEnum.EXCEPTION, "", (retryTimes + 1));
            }
        }
    }

    /**
     * 天秤返回额度后业务处理
     *
     * @param amountResultDTO  天秤反回结果
     * @param loanBusinessInfo 产品配置信息
     * @param project          标的信息
     */
    public void teAmountPostProcessing(TcCreditAmountResultDTO amountResultDTO, LoanBusinessInfo loanBusinessInfo, Project project) {
        log.info("天秤返回额度后业务处理: amountResultDTO={}, project={}", JSON.toJSONString(amountResultDTO), JSON.toJSONString(project));
        Long flowExecuteId = Long.valueOf(amountResultDTO.getReserve());
        Long projectId = project.getProjectId();

        if (amountResultDTO.getCreditAmount().compareTo(loanBusinessInfo.getMinAmount()) < 0) {
            log.info("天秤返回额度 < 产品的起借金额: amountResultDTO={} loanBusinessInfo={}", JSON.toJSONString(amountResultDTO), JSON.toJSON(loanBusinessInfo));
            StringBuffer errMsg = new StringBuffer("flowExecuteId=").append(flowExecuteId).append(" projectId=").append(projectId).append("天秤返回的额度低于产品的起借金额");

            // 流标
            ProjectFlowRequestDTO projectFlowRequestDTO = new ProjectFlowRequestDTO();
            projectFlowRequestDTO.setProjectId(projectId);
            projectFlowRequestDTO.setSubStatus(ProjectSubStatusEnum.MISCARRY_CREDIT_AMOUNT);
            projectDubboService.flow(projectFlowRequestDTO);

            // 限制用户借款行
            AddUserLoanLimitRequestDTO addUserLoanLimitRequestDTO = new AddUserLoanLimitRequestDTO();
            addUserLoanLimitRequestDTO.setLimitDays(Integer.valueOf(tradeConfigDubboService.selectTradeConfigByEmun(TradeConfigEnum.CARDNIU_HITCREDITMODELLIMITDAYS)));
            addUserLoanLimitRequestDTO.setLimitType(LibraLoanLimitEnum.CREDIT_AMOUNT_LESS.getLimitType().intValue());
            addUserLoanLimitRequestDTO.setUserId(project.getBorrowUserId());
            addUserLoanLimitRequestDTO.setProductTypeEnum(ProductTypeEnum.enumOf(loanBusinessInfo.getProductType()));
            CompletableFuture.runAsync(() -> userForbidDubboService.addUserLibraLoanLimit(addUserLoanLimitRequestDTO));

            // 结束流程
            projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK, errMsg.toString());

        } else if (amountResultDTO.getCreditAmount().compareTo(loanBusinessInfo.getMinAmount()) >= 0
                && amountResultDTO.getCreditAmount().compareTo(project.getContractAmount()) < 0) {
            log.info("天秤返回的额度 >= 起借金额 || 天秤返回的额度 <= 借款金额: amountResultDTO={} loanBusinessInfo={} project={}", JSON.toJSONString(amountResultDTO), JSON.toJSON(loanBusinessInfo), JSON.toJSON(project));

            // 提额成功更新标状态为审核通过待确认
            this.updateTeProjectStatus(project, ProjectStatusEnum.CHECKING, ProjectSubStatusEnum.CHECKING_FOR_CONFIRM, TeProjectFlagEnum.YES);

            // 成功结束标的申请流程
            projectFlowExecuteService.successEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.LOAN_TE_LIMIT_SCORE_BACK);

            // 发送站内信和短信提醒
            creditAmountNotificationsService.auditConfirmationNotice(project);

        } else if (amountResultDTO.getCreditAmount().compareTo(project.getContractAmount()) >= 0) {
            log.info("天秤返回的额度 >= 借款金额: amountResultDTO={} project={}", JSON.toJSONString(amountResultDTO), JSON.toJSON(project));

//            // 上标至存管
//            PushProjectRequestDTO pushProjectRequestDTO = new PushProjectRequestDTO();
//            pushProjectRequestDTO.setProjectId(project.getProjectId());
//            pushProjectRequestDTO.setPushFromEnum(PushProjectRequestDTO.PushFromEnum.AUTO_AUDIT);
//            iSpeedLoanFactory.adaptive(project).pushProject(pushProjectRequestDTO);

            ProjectWaitPublishReqDTO projectWaitPublishReqDTO=new ProjectWaitPublishReqDTO ();
            projectWaitPublishReqDTO.setProjectId(project.getProjectId());
            projectWaitPublishReqDTO.setPushFromEnum(ProjectWaitPublishReqDTO.PushFromEnum.AUTO_AUDIT);

            //标的进入待发布列表
            rabbitTemplate.convertAndSend(MqConstant.PROJECT_WAIT_PUBLISH_EXCHANGE, MqConstant.PROJECT_WAIT_PUBLISH_ROUTING, projectWaitPublishReqDTO);

            // 成功结束标的申请流程
            projectFlowExecuteService.successEndProjectFlowExecute(flowExecuteId, LoanNodeTypeEnum.PROJECT_TO_BANK);
        }
    }

    public void teFlowErrorProcess(LoanNodeTypeEnum loanNodeTypeEnum, Long flowExecuteId, String userId, Long projectId, String errMsg) {
        Project project = projectMapperExt.selectProjectByUserIdProjectId(userId, projectId);

        projectFlowExecuteService.failEndProjectFlowExecute(flowExecuteId, loanNodeTypeEnum, errMsg);

        project.setTeProjectFlag(TeProjectFlagEnum.YES.getValue());
        project.setStatus(ProjectStatusEnum.CHECKING.getStatus());
        project.setSubStatus(ProjectSubStatusEnum.CHECKING_FOR_CONFIRM.getSubStatus());
        project.setUpdateTime(new Date());
        projectMapperExt.updateByUserIdProjectSelective(project);

        creditAmountNotificationsService.auditConfirmationNotice(project);
    }
}










































